package com.sacc.util;

/**
 * @author 滚~韬
 * @date 2022/5/17 14:47
 */

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.power.common.util.RandomUtil;
import com.sacc.pojo.OrderStateAll;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import okhttp3.HttpUrl;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.*;


@Component
public class WXPayUtil {

    private static Logger log = LoggerFactory.getLogger(WXPayUtil.class);
    //公众账号ID
    public final static String NOTIFYURL = "https://www.fengxiangyunchang.cn/order/ordernumber/callback";//支付成功回调地址
    //public final  static  String NOTIFYURL = "https://www.weixin.qq.com";
    public final static String MERCHANTID = "1625981159"; // 商户号
    public final static String APIV3KEY = "Beesharingfengyuemeet12345678908"; // apiV3密钥
    public final static String WECHATPAYSERIAL = ""; // 平台证书序列号
    public final static String APPID = "wxf3816c432e179088";
    public final static String MERCHANTSERIALNUMBER = "65E100FE06EB896258D2202409F5E336C34351FE"; // 商户证书序列号
    public final static String REQUESTBODY = "{\n"
            + "    \"stock_id\": \"9433645\",\n"
            + "    \"stock_creator_mchid\": \"1900006511\",\n"
            + "    \"out_request_no\": \"20190522_001中文11\",\n"
            + "    \"appid\": \"wxab8acb865bb1637e\"\n"
            + "}";
    // 你的商户私钥
    public final static String PRICATEKEY = "-----BEGIN PRIVATE KEY-----\n" +
            "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDh8jzi249xLwh4\n" +
            "tD/5tsYkWCp+zpTJ0/xvF7sZbIK9BZstdytWbyUuuq4tLtooMfQN97DeMnS5rlIs\n" +
            "oDbcH1RkEXeCuF5ByGqDyYzC8pmPNG16+wR8ZIq1N3O7gXafgHZ8p5dk8pZK5TKM\n" +
            "6Gdil1XNqFGwuegdnpha7FvtnpUOVpWxR1P1tudamkLhHDd6TCYSw6LQmILMB1RE\n" +
            "zsuQnXOiAYxFIfirlnocedAapvVZvrpkiN2k9/PzPkgPLHrH35f0ZdZ61fbVQgBu\n" +
            "zWCZfCGBwaBfdOakuQhLlA2abQYp0V5gdVsv2VT0pkvY9kFh26eKss/T/hpfth+W\n" +
            "L2Kzkw+3AgMBAAECggEAeJSNN8hSyeV+0OPpDHwlTDodG6VltDxEiIkSmaPWNcgr\n" +
            "I11orG0OW9zWnVhWpoLaKyYXps0oi/ti8VvjSyARKoJD1GhOLS8m4QQL8fIET298\n" +
            "SdhycWw6tjFMuzGBO+gT07ygyAfKe1fL3XUdz3jSGroMNpNQM5Zy2nsvKCWsiIRe\n" +
            "EVUBR/Qx/7tF+Xk/TRB/wXC24Dy4x3BQs+OO+hpx2KzupagDJaR2h5phTMGnIgSe\n" +
            "Ebe3V6DUjCbpnkxImTxM05mmAsVhxjAYcdl2qTgOQOMm0IXXco7DAoFHZUAfMmcP\n" +
            "9bXWaJWL08769qIeULXnZtuG4oOQsAswgKEXGE6v0QKBgQDzBtwm2gcHmKdx+2fP\n" +
            "hv9LOQgyG9ywS7tDQ2vr28UwbaP2RO80TjHczl5mhJk/tX6Mi8MJTSK5DE6v4NR0\n" +
            "CXl0exzLsqfVTeuXnf8ySw1i4qhjkArdAEvhUX4jA/bwhk4p80gVlf5Ye/ZLKFX9\n" +
            "FntERltk7nKy/6jWNzpoXjrnaQKBgQDuAfWijNBdn9/JlGIfKbFnhHL3qd39WTIS\n" +
            "5HFlkXOrufDlZ+dXRR33G5TFTHTIo13q6ih+/rsxe2TtjeaceamDpUWp0TloBqsz\n" +
            "jUxWFxtBOVb49fB308v3D7hQrSuAsomfEO40wXYtyahKIwPKY6G8TaNFhd4twGRq\n" +
            "Ao0ScsF6HwKBgQC0tMYgUYBmopjnhTPkuRG9glPYxqTrpfRBiLGHuGvAndYMOafQ\n" +
            "MdCbyguhmTlGiRLnOMk2cle+VytvVfNDsQPRm/WGdXqcfgsPOxlV8T6r57OkDKg3\n" +
            "OpAxo2HycXE92e/m+5H/EwAEFXDG4+BEh2HzG4m73B4HgViuqHRSxLZx+QKBgGdu\n" +
            "4JH4wiC99uJCovXKB7fl/pSU9M1CMxm0v3cVZABwOTlpE0eA2QnnqZqopGQBYzJQ\n" +
            "+rJd/3n8lxsJvPupf7qfW4v2Sg1kQIiR0mfjeMu6oIpnT06z84L2CPK+nxY6AMbo\n" +
            "86xnmvVBGurFFsOg0svjrZ3sFGcrojfTzf0DdAOfAoGBAJumQ592uj8upYRTdcNE\n" +
            "lGAElm2WwOTQ02sqkbeAE1o8gXLkJsfnLXGmrmG1mVEcdsHxiMQ7GlqW4uv+Q3lC\n" +
            "QsSwCW7zntpfrv2Vmm+TP7C/7SBQlhEjjzDVMIAsrojWu9MkbcSLJWWa7fCkcms/\n" +
            "7Ak8p4OQQXJ5eUirNwx+4svf\n" +
            "-----END PRIVATE KEY-----";
    // 你的微信支付平台证书
    public final static String CERTIFICATE = "-----BEGIN CERTIFICATE-----\n" +
            "MIID4zCCAsugAwIBAgIUURAb3/WLJmnMhjeLPOc9ChtmM5kwDQYJKoZIhvcNAQEL\n" +
            "BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT\n" +
            "FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg\n" +
            "Q0EwHhcNMjIwNTE3MTA1MDM3WhcNMjcwNTE2MTA1MDM3WjB1MRMwEQYDVQQDDAox\n" +
            "NjI1OTgxMTU5MRswGQYDVQQKDBLlvq7kv6HllYbmiLfns7vnu58xITAfBgNVBAsM\n" +
            "GOeOhOatpuicgue6pumjn+WTgeWVhuihjDELMAkGA1UEBgwCQ04xETAPBgNVBAcM\n" +
            "CFNoZW5aaGVuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw4uEmROm\n" +
            "BDl+B5Oe67Kh1paBIhcj5T3MR4wPSqJocdgV1DLm78zORStw4uFrgs5tfYxJtYgb\n" +
            "4FKpSJi4FewO9t9rDTUXvonefuqQUSqSEJ9Dv6wLyBNueV2AJq5arW+WWHdBEjDV\n" +
            "SFftSdyaZlCkJvd3sSUjEj+m+ZzBJb5ntG65ZP24cND9+TeMYBxsn6mEUSPgk8Hg\n" +
            "GfR8isx2CwGO1LWhxdsGdl1FPIkC94A+k2Umx7+F3Hjzl+QD0fnIk+iNJf5T+2Rp\n" +
            "1MNwOtD0/izB+i/ozIOM2KP0AnEzxRYp/eZCpx55smK5O0poKwLZ/Fq6rX6LLkSp\n" +
            "uJ6GcWADAK/GgQIDAQABo4GBMH8wCQYDVR0TBAIwADALBgNVHQ8EBAMCBPAwZQYD\n" +
            "VR0fBF4wXDBaoFigVoZUaHR0cDovL2V2Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9p\n" +
            "dHJ1c2NybD9DQT0xQkQ0MjIwRTUwREJDMDRCMDZBRDM5NzU0OTg0NkMwMUMzRThF\n" +
            "QkQyMA0GCSqGSIb3DQEBCwUAA4IBAQBGLjJokgHivKtUxmjjCYS2w1eNPww0JYM6\n" +
            "3gtqKiX0wGN+TUW/yraztFmYaxkxpmP6Y6h6E0r+pbJodbEqF45iAZz9skmMsV1r\n" +
            "CUVZsYsKLaKOQafG0WHKjUBm5jQQnWBHw/iW1dtURwMOOcoVPcziTEKBqcAeEtm4\n" +
            "AeEG6UOWRE6SLZ9OvXZo643YZXBz9V7M/Z4T63DKJOLg4oxzj/hXi5lGHU94wkBI\n" +
            "Yk9J5fJwCFF3ygmqK1wtXie0byISrRo4XlivmsOElVKY3TZRbQxS0gndTEOnc3Vm\n" +
            "PAZo7M/R19FkkrL1ZBZ+pUuombpGjpx37yc7GrSIRToVssr9u1bx\n" +
            "-----END CERTIFICATE-----";
    //商户号
    public final static String MCHID = "1625981159";
    //商户密钥
    public final static String APPSECRET = "66bc191042f155e64f24317bd8691806";
    //虽然官方文档不是必须参数，但是不送有时候会验签失败
    public final static String MD5 = "MD5";
    //退款需要的证书路径
    public final static String certifi_path = "/data/...";
    //H5支付标记
    public final static String trade_type = "JSAPI";

    //调用统一下单时需要提供得回调接口
    public final static String callback_notify = "http://.../sub/json/notifyOrder";

    //获取code接口
    public final static String getCodeUrl = " https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + APPID + "&redirect_uri=http://114.gxtx.163.cn/weixin/login&response_type=code&scope=snsapi_base&state=123#wechat_redirect";

    //获取网页授权登录access_token 接口地址Get
    public final static String OAUTH_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";

    //微信统一下单接口
    public final static String ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    //微信退款接口
    public final static String REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
    //微信查询订单
    public final static String QUERY_ORDER_STATUS = "https://api.mch.weixin.qq.com/pay/orderquery";

    /**
     * Md5 加密工具
     *
     * @param s String   not null
     * @return 加密后的 MD5 值 32位大写的
     */
    public static String md5(String s) {
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        try {
            byte[] btInput = s.getBytes();
            // 获得MD5摘要算法的 MessageDigest 对象
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // 使用指定的字节更新摘要
            mdInst.update(btInput);
            // 获得密文
            byte[] md = mdInst.digest();
            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 生成 HMACSHA256
     *
     * @param data 待处理数据
     * @param key  密钥
     * @return 加密结果
     * @throws Exception
     */
    public static String HMACSHA256(String data, String key) throws Exception {
        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
        sha256_HMAC.init(secret_key);
        byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }


    /**
     * 生成签名. 注意，若含有sign_type字段，必须和signType参数保持一致。
     *
     * @param data 待签名数据
     * @return 签名
     */
    public static String generateSignature(Map<String, String> data) throws Exception {
        Set<String> keySet = data.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            if ("sign".equals(k)) {
                continue;
            }
            if (data.get(k).trim().length() > 0) // 参数值为空，则不参与签名
                sb.append(k).append("=").append(data.get(k).trim()).append("&");
        }
        sb.append("key=").append(APPSECRET);
        return md5(sb.toString()).toUpperCase();
    }


    /**
     * 生成字母+数字（8位）随机数
     *
     * @param length 长度
     * @return val 转换好的文本
     */
    public static String getStringRandom(int length) {
        String val = "";
        Random random = new Random();
        //length为几位密码
        for (int i = 0; i < length; i++) {
            String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
            //输出字母还是数字
            if ("char".equalsIgnoreCase(charOrNum)) {
                //输出是大写字母还是小写字母
                int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
                val += (char) (random.nextInt(26) + temp);
            } else if ("num".equalsIgnoreCase(charOrNum)) {
                val += String.valueOf(random.nextInt(10));
            }
        }
        return val;
    }

    /**
     * 元转换成分
     *
     * @param amount
     * @return
     */
    public static String getMoney(String amount) {
        if (amount == null) {
            return "";
        }
        // 金额转化为分为单位
        String currency = amount.replaceAll("\\$|\\￥|\\,", "");  //处理包含, ￥ 或者$的金额
        int index = currency.indexOf(".");
        int length = currency.length();
        Long amLong = 0l;
        if (index == -1) {
            amLong = Long.valueOf(currency + "00");
        } else if (length - index >= 3) {
            amLong = Long.valueOf((currency.substring(0, index + 3)).replace(".", ""));
        } else if (length - index == 2) {
            amLong = Long.valueOf((currency.substring(0, index + 2)).replace(".", "") + 0);
        } else {
            amLong = Long.valueOf((currency.substring(0, index + 1)).replace(".", "") + "00");
        }
        return amLong.toString();
    }




    /**
     * description: 解析微信通知xml
     *
     * @param xml
     * @return
     * @author ex_yangxiaoyi
     * @see
     */
//    @SuppressWarnings({"unused", "rawtypes", "unchecked"})
//    public static Map parseXmlToList(String xml) {
//        Map retMap = new HashMap();
//        try {
//            StringReader read = new StringReader(xml);
//            // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
//            InputSource source = new InputSource(read);
//            // 创建一个新的SAXBuilder
//            SAXBuilder sb = new SAXBuilder();
//            // 通过输入源构造一个Document
//            Document doc = (Document) sb.build(source);
//            Element root = doc.getRootElement();// 指向根节点
//            List<Element> es = root.getChildren();
//            if (es != null && es.size() != 0) {
//                for (Element element : es) {
//                    retMap.put(element.getName(), element.getValue());
//                }
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return retMap;
//
//    }

    /**
     * 获取用户实际ip
     *
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ipAddress = request.getHeader("x-forwarded-for");
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
                //根据网卡取本机配置的IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                ipAddress = inet.getHostAddress();
            }
        }
        //对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (ipAddress != null && ipAddress.length() > 15) { //"***.***.***.***".length() = 15
            if (ipAddress.indexOf(",") > 0) {
                ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
            }
        }
        return ipAddress;
    }


    private static int socketTimeout = 10000;// 连接超时时间，默认10秒
    private static int connectTimeout = 30000;// 传输超时时间，默认30秒
    private static RequestConfig requestConfig;// 请求器的配置

    String schema = "WECHATPAY2-SHA256-RSA2048";
    String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) {
        String canonicalUrl = url.encodedPath();
        if (url.encodedQuery() != null) {
            canonicalUrl += "?" + url.encodedQuery();
        }

        return method + "\n"
                + canonicalUrl + "\n"
                + timestamp + "\n"
                + nonceStr + "\n"
                + body + "\n";
    }
    public static String sign(byte[] message) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {
        PrivateKey merchantPrivatekey = PemUtil.loadPrivateKey(PRICATEKEY);
        System.out.println(merchantPrivatekey);
        Signature sign = Signature.getInstance("SHA256withRSA");
        sign.initSign(merchantPrivatekey);
        sign.update(message);
        return Base64.getEncoder().encodeToString(sign.sign());
    }
//    private CertificatesManager certificatesManager;
//    private Verifier verifier;
    public Map CreateOrderNumber(OrderStateAll stateAll) throws Exception {
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(PRICATEKEY);
        // 获取证书管理器实例
        CertificatesManager certificatesManager = CertificatesManager.getInstance();
        // 向证书管理器增加需要自动更新平台证书的商户信息
        certificatesManager.putMerchant(WXPayUtil.MERCHANTID, new WechatPay2Credentials(WXPayUtil.MERCHANTID,
                        new PrivateKeySigner(WXPayUtil.MERCHANTSERIALNUMBER, merchantPrivateKey)),
                WXPayUtil.APIV3KEY.getBytes(StandardCharsets.UTF_8));
        // 从证书管理器中获取verifier
        Verifier verifier = certificatesManager.getVerifier(WXPayUtil.MERCHANTID);
        CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create()
                .withMerchant(WXPayUtil.MERCHANTID, WXPayUtil.MERCHANTSERIALNUMBER, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(certificatesManager.getVerifier(WXPayUtil.MERCHANTID)))
                .build();

        String timestamp = System.currentTimeMillis()+"";
        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type","application/json; charset=utf-8");

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectMapper objectMapper = new ObjectMapper();

        ObjectNode rootNode = objectMapper.createObjectNode();
        rootNode.put("mchid",WXPayUtil.MCHID)
                .put("appid", WXPayUtil.APPID)
                .put("description", "蜂缘"+stateAll.getOrderNumber())
                .put("notify_url", WXPayUtil.NOTIFYURL)
                .put("out_trade_no", stateAll.getOrderNumber());
        rootNode.putObject("amount")
                .put("total", stateAll.getTotal());
        rootNode.putObject("payer")
                .put("openid", stateAll.getOpenId());

        objectMapper.writeValue(bos, rootNode);

        httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
        CloseableHttpResponse response = httpClient.execute(httpPost);

        String bodyAsString = EntityUtils.toString(response.getEntity());

//        System.out.println(bodyAsString);


        String nonce = RandomUtil.randomString(32);
        StringBuilder builder = new StringBuilder();
        //应用id
        builder.append(WXPayUtil.APPID).append("\n");
        //时间戳
        builder.append(timestamp).append("\n");
        //随机字符串
        builder.append(nonce).append("\n");
        JsonNode node = objectMapper.readTree(bodyAsString);
        //预支付交易会话ID
        builder.append("prepay_id="+node.get("prepay_id").toString().replace("\"","")).append("\n");
        String ciphertext = sign(builder.toString().getBytes(StandardCharsets.UTF_8));
//        System.out.println(ciphertext);
        Map map = new HashMap();
        map.put("timestamp",timestamp);
        map.put("noncestr",nonce);
        map.put("package","prepay_id="+node.get("prepay_id").toString().replace("\"",""));
        map.put("signType","RSA");
        map.put("paySign",ciphertext);
        return map;
    }
    public static boolean signVerify(String serialNumber,String message,String signature) throws NotFoundException, GeneralSecurityException, IOException, HttpCodeException {
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(PRICATEKEY);
        // 获取证书管理器实例
        CertificatesManager certificatesManager = CertificatesManager.getInstance();
        // 向证书管理器增加需要自动更新平台证书的商户信息
        certificatesManager.putMerchant(WXPayUtil.MERCHANTID, new WechatPay2Credentials(WXPayUtil.MERCHANTID,
                        new PrivateKeySigner(WXPayUtil.MERCHANTSERIALNUMBER, merchantPrivateKey)),
                WXPayUtil.APIV3KEY.getBytes(StandardCharsets.UTF_8));
        // 从证书管理器中获取verifier
        Verifier verifier = certificatesManager.getVerifier(WXPayUtil.MERCHANTID);

        return verifier.verify(serialNumber, message.getBytes(StandardCharsets.UTF_8), signature);
    }
    public static String decryptOrder(String body){
        try{
            AesUtil aesUtil = new AesUtil(APIV3KEY.getBytes(StandardCharsets.UTF_8));
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode node = objectMapper.readTree(body);
            JsonNode resource = node.get("resource");
            String ciphertext = resource.get("ciphertext").textValue();
            String associatedData = resource.get("associated_data").textValue();
            String nonce = resource.get("nonce").textValue();
            return aesUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8), nonce.getBytes(StandardCharsets.UTF_8), ciphertext);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public static String closeOrder(String outTradeNo) throws Exception {
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(PRICATEKEY);
        // 获取证书管理器实例
        CertificatesManager certificatesManager = CertificatesManager.getInstance();
        // 向证书管理器增加需要自动更新平台证书的商户信息
        certificatesManager.putMerchant(WXPayUtil.MERCHANTID, new WechatPay2Credentials(WXPayUtil.MERCHANTID,
                        new PrivateKeySigner(WXPayUtil.MERCHANTSERIALNUMBER, merchantPrivateKey)),
                WXPayUtil.APIV3KEY.getBytes(StandardCharsets.UTF_8));
        // 从证书管理器中获取verifier
        Verifier verifier = certificatesManager.getVerifier(WXPayUtil.MERCHANTID);
        CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create()
                .withMerchant(WXPayUtil.MERCHANTID, WXPayUtil.MERCHANTSERIALNUMBER, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(certificatesManager.getVerifier(WXPayUtil.MERCHANTID)))
                .build();


        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/"+outTradeNo+"/close");
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type","application/json; charset=utf-8");

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectMapper objectMapper = new ObjectMapper();

        ObjectNode rootNode = objectMapper.createObjectNode();
        rootNode.put("mchid",MCHID);

        objectMapper.writeValue(bos, rootNode);

        httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
        CloseableHttpResponse response = httpClient.execute(httpPost);
        if(response==null){
            return "关闭成功";
        }
        String bodyAsString = EntityUtils.toString(response.getEntity());
        return  bodyAsString;
    }
    public static String queryOrder(String outTradeNo) throws Exception {
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(PRICATEKEY);
        // 获取证书管理器实例
        CertificatesManager certificatesManager = CertificatesManager.getInstance();
        // 向证书管理器增加需要自动更新平台证书的商户信息
        certificatesManager.putMerchant(WXPayUtil.MERCHANTID, new WechatPay2Credentials(WXPayUtil.MERCHANTID,
                        new PrivateKeySigner(WXPayUtil.MERCHANTSERIALNUMBER, merchantPrivateKey)),
                WXPayUtil.APIV3KEY.getBytes(StandardCharsets.UTF_8));
        // 从证书管理器中获取verifier
        Verifier verifier = certificatesManager.getVerifier(WXPayUtil.MERCHANTID);
        CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create()
                .withMerchant(WXPayUtil.MERCHANTID, WXPayUtil.MERCHANTSERIALNUMBER, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(certificatesManager.getVerifier(WXPayUtil.MERCHANTID)))
                .build();

        URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/"+outTradeNo+"?mchid="+MCHID);
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.addHeader("Accept", "application/json");
        CloseableHttpResponse response = httpClient.execute(httpGet);
        String bodyAsString = EntityUtils.toString(response.getEntity());
        return bodyAsString;
    }
}
